#!/bin/bash
function check_parm() {
    if [ "$2" == "" ];then
        echo -n "$1"
        return 1
    else
        return 0
    fi
}

if [ -f ./ldap.info ]; then
    source ./ldap.info
fi

check_parm "Enter the IP address of server-01: " $NODE1_IP
[ $? -eq 1 ] && { read NODE1_IP; echo "NODE1_IP=$NODE1_IP" >./ldap.info; }

check_parm "Enter the Hostname of server-01: " $NODE1_HOSTNAME
[ $? -eq 1 ] && { read NODE1_HOSTNAME; echo "NODE1_HOSTNAME=$NODE1_HOSTNAME" >>./ldap.info; }

check_parm "Enter the server-01 ssh root password: " $NODE1_ROOTPASS
[ $? -eq 1 ] && { read NODE1_ROOTPASS; echo "NODE1_ROOTPASS=$NODE1_ROOTPASS" >>./ldap.info; }

check_parm "Enter the IP address of server-02: " $NODE2_IP
[ $? -eq 1 ] && { read NODE2_IP; echo -e "\nNODE2_IP=$NODE2_IP" >>./ldap.info; }

check_parm "Enter the Hostname of server-02: " $NODE2_HOSTNAME
[ $? -eq 1 ] && { read NODE2_HOSTNAME; echo "NODE2_HOSTNAME=$NODE2_HOSTNAME" >>./ldap.info; }

check_parm "Enter the server-02 ssh root password: " $NODE2_ROOTPASS
[ $? -eq 1 ] && { read NODE2_ROOTPASS; echo "NODE2_ROOTPASS=$NODE2_ROOTPASS" >>./ldap.info; }

check_parm "Enter the LDAP manager user admin password: " $ADMIN_PASS
[ $? -eq 1 ] && { read ADMIN_PASS; echo "ADMIN_PASS=$ADMIN_PASS" >>./ldap.info; }

# 比较两台主机名后缀是否相同
NODE1_DN=$(echo $NODE1_HOSTNAME | awk -F '.'  '{print $2"."$3}')
NODE2_DN=$(echo $NODE2_HOSTNAME | awk -F '.'  '{print $2"."$3}')
if [ "$NODE1_DN" == "$NODE2_DN" ]; then
    BASE_DN=$NODE1_DN
    dc1=$(echo $BASE_DN | awk -F '.' '{print $1}')
    dc2=$(echo $BASE_DN | awk -F '.' '{print $2}')
else
    echo "Error: check server Hostname"
    exit 1
fi

clear
echo """
ldap.info

    server-01
      IP:         $NODE1_IP
      HOSTNSME:   $NODE1_HOSTNAME
      ROOTPASS:   $NODE1_ROOTPASS

    server-02
      IP:         $NODE2_IP
      HOSTNSME:   $NODE2_HOSTNAME
      ROOTPASS:   $NODE2_ROOTPASS

    BASE DN:  dc=$dc1, dc=$dc2

    manager user info
      user:      admin
      passwd:    $ADMIN_PASS
"""

while [ "$AGREE" != "yes" ]; do
    if [ "$AGREE" == "no" ]; then
        exit 0;
    else
        echo -n 'Please print "yes" to continue or "no" to cancle: '
        read AGREE
    fi
done

IPS=(${NODE1_IP} ${NODE2_IP})
HOSTS=(${NODE1_HOSTNAME} ${NODE2_HOSTNAME})
ROOTPASS=(${NODE1_ROOTPASS} ${NODE2_ROOTPASS})

# yum 源
rm -f /etc/yum.repos.d/*
curl -so /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
sed -i '/aliyuncs.com/d' /etc/yum.repos.d/Centos-7.repo /etc/yum.repos.d/epel-7.repo

# 安装 expect
which expect >/dev/null 2>&1 || yum install -y expect

# 生成 SSHKey
[ -f ~/.ssh/id_dsa ] || ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

# 免密码登陆
function ssh_key() {
/usr/bin/expect <<EOF
set timeout 30
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub root@$1
expect {
    "(yes/no)?" { send "yes\r"; exp_continue }
    "password:" { send "$2\r" }
  }
expect eof
EOF
}

ssh_key ${IPS[0]} ${ROOTPASS[0]}
ssh_key ${IPS[1]} ${ROOTPASS[1]}

# 初始化环境及安装
for index in 0 1;do
    IP=${IPS[$index]}
    HOST=${HOSTS[$index]}
    ssh -T $IP <<EOF
      hostnamectl set-hostname $HOST
      echo "${IPS[0]}    ${HOSTS[0]}" >>/etc/hosts
      echo "${IPS[1]}    ${HOSTS[1]}" >>/etc/hosts

      # 防火墙允许ldap端口 389,636
      firewall-cmd --zone=public --add-port=389/tcp --permanent
      firewall-cmd --zone=public --add-port=636/tcp --permanent
      firewall-cmd --zone=public --add-port=80/tcp --permanent
      firewall-cmd --reload

      # selinux
      setenforce 0
      sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

      # yum 源
      rm -f /etc/yum.repos.d/*
      curl -so /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
      curl -so /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
      sed -i '/aliyuncs.com/d' /etc/yum.repos.d/Centos-7.repo /etc/yum.repos.d/epel-7.repo

      # 安装 openldap
      yum install -y openldap openldap-devel openldap-servers openldap-clients openldap-devel compat-openldap ntpdate vim net-tools

      # 时间同步
      /usr/sbin/ntpdate ntp6.aliyun.com ;hwclock -w
      echo -e '*/3 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1 && /usr/sbin/hwclock -w' > /tmp/crontab
      crontab /tmp/crontab
EOF
done

# 生成证书
ssh -T ${IPS[0]} <<EOS
  # CA中心生成自身私钥
  cd /etc/pki/CA
  rm -f serial index.txt
  (umask 077;openssl genrsa -out private/cakey.pem 2048)

  # CA签发自身公钥
  openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 \
    -subj "/C=CN/ST=HuBei/L=WuHan/O=$dc1/OU=$BASE_DN/CN=*.$BASE_DN/emailAddress=544025211@qq.com"
  touch serial index.txt
  echo "01" > serial

  # 查看根证书信息
  openssl x509 -noout -text -in /etc/pki/CA/cacert.pem

  # 生成OpenLdap服务器证书
  mkdir /etc/openldap/ssl
  cd /etc/openldap/ssl
  (umask 077;openssl genrsa -out ldapkey.pem 1024)

  # 申请证书签署请求
  openssl req -new -key ldapkey.pem -out ldap.csr -days 3650 \
    -subj "/C=CN/ST=HuBei/L=WuHan/O=$dc1/OU=$BASE_DN/CN=*.$BASE_DN/emailAddress=544025211@qq.com"

# CA核实并发证书
yum install -y expect
/usr/bin/expect <<EOF
    set timeout 30
    spawn openssl ca -in ldap.csr -out ldapcert.pem -days 3650
    expect {
        "*:" { send "Y\r" ; exp_continue}
        "*]" { send "Y\r" ; exp_continue}
        eof { exit }
    }
EOF
cp /etc/pki/CA/cacert.pem /etc/openldap/ssl

# 查看生成的证书
openssl x509 -noout -text -in ldapcert.pem
EOS

# 传送证书
scp -r ${IPS[0]}:/etc/openldap/ssl/ /root/
scp -r /root/ssl/ ${IPS[1]}:/etc/openldap/
rm -rf /root/ssl

# 生成加密密码字符
pass="$ADMIN_PASS"
ldap_pass=$(ssh ${IPS[0]} "slappasswd -s $pass -n")

# 双主同步配置
NODE1_INFO="""
moduleload syncprov.la
modulepath /usr/lib64/openldap

index   entryCSN,entryUUID    eq

overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100

serverID  1

syncrepl  rid=001
    provider=ldaps://${HOSTS[1]}
    bindmethod=simple
    binddn=\"cn=admin,dc=$dc1,dc=$dc2\"
    credentials='$pass'
    searchbase=\"dc=$dc1,dc=$dc2\"
    schemachecking=on
    type=refreshAndPersist
    starttls=yes
    retry=\"60 +\"

mirrormode on
"""

NODE2_INFO="""
moduleload syncprov.la
modulepath /usr/lib64/openldap

index   entryCSN,entryUUID    eq

overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100

serverID  2

syncrepl  rid=001
    provider=ldaps://${HOSTS[0]}
    bindmethod=simple
    binddn=\"cn=admin,dc=$dc1,dc=$dc2\"
    credentials='$pass'
    searchbase=\"dc=$dc1,dc=$dc2\"
    schemachecking=on
    type=refreshAndPersist
    starttls=yes
    retry=\"60 +\"

mirrormode on
"""

# 生成配置文件
mkdir /root/openldap
for index in 0 1; do
    IP=${IPS[$index]}
    HOST=${HOSTS[$index]}
    echo """
include     /etc/openldap/schema/corba.schema
include     /etc/openldap/schema/core.schema
include     /etc/openldap/schema/cosine.schema
include     /etc/openldap/schema/duaconf.schema
include     /etc/openldap/schema/dyngroup.schema
include     /etc/openldap/schema/inetorgperson.schema
include     /etc/openldap/schema/java.schema
include     /etc/openldap/schema/misc.schema
include     /etc/openldap/schema/nis.schema
include     /etc/openldap/schema/openldap.schema
include     /etc/openldap/schema/ppolicy.schema
include     /etc/openldap/schema/collective.schema

allow       bind_v2
pidfile     /var/run/openldap/slapd.pid
argsfile    /var/run/openldap/slapd.args

modulepath  /usr/lib64/openldap
moduleload  ppolicy.la

TLSCACertificateFile  /etc/openldap/ssl/cacert.pem
TLSCertificateFile  /etc/openldap/ssl/ldapcert.pem
TLSCertificateKeyFile  /etc/openldap/ssl/ldapkey.pem
TLSVerifyClient never

access to attrs=shadowLastChange,userPassword
    by self write
    by * auth

access to *
    by * read

database config
access to *
    by dn.exact=\"gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth\" manage
    by * none

database monitor
access to *
    by dn.exact=\"gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth\" read
        by dn.exact=\"cn=admin,dc=$dc1,dc=$dc2\" read
        by * none

database    hdb
suffix      \"dc=$dc1,dc=$dc2\"
checkpoint  1024 15
rootdn      \"cn=admin,dc=$dc1,dc=$dc2\"
rootpw      $ldap_pass
directory   /var/lib/ldap

index    objectClass                       eq,pres
index    ou,cn,mail,surname,givenname      eq,pres,sub
index    uidNumber,gidNumber,loginShell    eq,pres
index    uid,memberUid                     eq,pres,sub
index    nisMapName,nisMapEntry            eq,pres,sub
loglevel    4095
""" >/root/openldap/slapd-${index}.conf

    if [ $index -eq 0 ];then
        echo """
$NODE1_INFO""" >>/root/openldap/slapd-${index}.conf
    elif [ $index -eq 1 ];then
        echo """
$NODE2_INFO""" >>/root/openldap/slapd-${index}.conf
    fi

    scp /root/openldap/slapd-${index}.conf $IP:/etc/openldap/slapd.conf

    ssh -T $IP <<EOF
      # 设置证书权限
      chown ldap:ldap /etc/openldap/ssl/*
      chmod 0400 /etc/openldap/ssl/*

      # 复制数据库配置文件
      cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
      chown -R ldap.ldap /var/lib/ldap/DB_CONFIG

      # 配置监听 slapd
      if [ ! -n "\$(grep 'SLAPD_URLS' /etc/sysconfig/slapd | grep 'ldaps')" ];then
          sed -i 's/SLAPD_URLS/#SLAPD_URLS/' /etc/sysconfig/slapd
          echo 'SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"' >>/etc/sysconfig/slapd
          echo 'SLAPD_LDAP=yes' >>/etc/sysconfig/slapd
          echo 'SLAPD_LDAPI=yes' >>/etc/sysconfig/slapd
          echo 'SLAPD_LDAPS=yes' >>/etc/sysconfig/slapd
      fi

      # 重新生成配置
      rm -rf /etc/openldap/slapd.d/*
      slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
      chown -R ldap.ldap /etc/openldap/slapd.d
      chown -R ldap.ldap /var/lib/ldap/
      systemctl restart slapd

      # 配置日志
      echo '# ldap log' >>/etc/rsyslog.conf
      echo 'local4.*    /var/log/slapd/slapd.log' >>/etc/rsyslog.conf
      systemctl restart rsyslog
EOF
done

# 导入本地用户息到 server-01
ssh -T ${IPS[0]} <<EOF
  # 创建测试用户
  for user in ldapuser{1..10} feng{1..10}; do
      useradd \$user
      echo redhat | passwd --stdin \$user
  done

  # 安装 migrationtools
  yum install -y migrationtools

  # 替换base dn信息
  sed -i '71 s/DEFAULT_MAIL_DOMAIN =.*/DEFAULT_MAIL_DOMAIN = "$BASE_DN";/' /usr/share/migrationtools/migrate_common.ph
  sed -i '74 s/DEFAULT_BASE =.*/DEFAULT_BASE = "dc=$dc1,dc=$dc2";/' /usr/share/migrationtools/migrate_common.ph
  sed -i 's/EXTENDED_SCHEMA = 0/EXTENDED_SCHEMA = 1/' /usr/share/migrationtools/migrate_common.ph

  # 生成ldif数据
  /usr/share/migrationtools/migrate_base.pl > ~/base.ldif
  /usr/share/migrationtools/migrate_passwd.pl  /etc/passwd > ~/passwd.ldif
  /usr/share/migrationtools/migrate_group.pl  /etc/group > ~/group.ldif

  # 导入数据
  ldapadd -x -w $pass -D "cn=admin,dc=$dc1,dc=$dc2" -f ~/base.ldif
  ldapadd -x -w $pass -D "cn=admin,dc=$dc1,dc=$dc2" -f ~/passwd.ldif
  ldapadd -x -w $pass -D "cn=admin,dc=$dc1,dc=$dc2" -f ~/group.ldif

  # 验证
  ldapsearch -x cn=feng1 -b dc=$dc1,dc=$dc2
EOF

# 重启 server-02 上的 slapd服务
ssh -T ${IPS[1]} "
    rm -f /var/lib/ldap/*
    systemctl restart slapd
    sleep 3
    ls /var/lib/ldap/
    sleep 3
    ldapsearch -x cn=feng1 -b dc=$dc1,dc=$dc2"
